/***************************************************************************
 *   Copyright (C) 2007 by Ivan Vasić                                      *
 *   ivasic@gmail.com                                                      *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "centralview.h"
#include "globals.h"
#include "trackerdb.h"
#include "sqlobjectsmodel.h"
#include "model.h"
#include "modeltorrent.h"
#include "modeluser.h"
#include "torrentpropertiesdialog.h"
#include "userpropertiesdialog.h"
#include "settingswidget.h"

#include "exporttorrentdialog.h"

#include "exceptions.h"
#include "exceptionhandler.h"


#include <QtGui>
#include <QtCore>

CentralView::CentralView(QWidget *parent)
		: QWidget(parent), m_torrents(0l), m_users(0l), m_filterModel(0l)
{
	setObjectName("Central View");

	setupUi(this);
	btnClearSearch->setIcon(QIcon(":/images/icons/clear_left.png"));

	m_filterModel = new QSortFilterProxyModel(this);
	m_filterModel->setDynamicSortFilter(true);

	m_torrents = Globals::instance().db()->createTorrentsSqlModel();
	m_users = Globals::instance().db()->createUsersSqlModel();


	setupWidgets();

	setupActions();
	setupConnections();

	propertiesView->insertHtml("<b>Properties View</b><br><br>Select item from list...");

	//QListView* listView;
	listView->setModel(m_filterModel);

	showTorrents();

	lblConnections->setText("0");

	updateLabels();
}

void CentralView::setupActions()
{
	actionRefresh = new QAction(QIcon(":/images/icons/normal.png"), tr("Refresh"), this);
	connect(actionRefresh, SIGNAL(triggered()), this, SLOT(refreshCurrentView()));

	actionRemoveItem =  new QAction(QIcon(":/images/icons/normal.png"), tr("Remove item"), this);
	connect(actionRemoveItem, SIGNAL(triggered()), this, SLOT(removeItem()));

	actionExportTorrent = new QAction(QIcon(":/images/icons/normal.png"), tr("Export torrent"), this);
	connect(actionExportTorrent, SIGNAL(triggered()), this, SLOT(slotExportTorrent()));

	actionShowTorrentPropertiesDialog = new QAction(QIcon(":/images/icons/normal.png"), tr("Properties"), this);
	connect(actionShowTorrentPropertiesDialog, SIGNAL(triggered()), this, SLOT(showTorrentPropertiesDialog()));

	actionShowUserPropertiesDialog = new QAction(QIcon(":/images/icons/normal.png"), tr("Properties"), this);
	connect(actionShowUserPropertiesDialog, SIGNAL(triggered()), this, SLOT(showUserPropertiesDialog()));
}

void CentralView::setupConnections()
{
	connect(listView, SIGNAL(clicked(const QModelIndex&)), this, SLOT(itemClicked(const QModelIndex&)));

	connect(listView, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(listViewContextMenuRequested(const QPoint&)));

	connect(m_searchLine, SIGNAL(textChanged(const QString&)), m_filterModel, SLOT(setFilterFixedString(const QString&)));

	connect(listView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(listViewDoubleClicked(QModelIndex)));
}

CentralView::~CentralView()
{
	deleteModels();
}


void CentralView::showTorrents()
{
	m_filterModel->setSourceModel(m_torrents);
	m_filterModel->setFilterKeyColumn(1);
	listView->setModelColumn(1);

	m_filterModel->sort(1, Qt::AscendingOrder);

	m_currentModel = m_torrents;

	clearPropertiesView();

	m_stack->setCurrentIndex(0);
}

void CentralView::showUsers()
{
	m_filterModel->setSourceModel(m_users);
	m_filterModel->setFilterKeyColumn(0);
	listView->setModelColumn(0);

	m_currentModel = m_users;

	clearPropertiesView();

	m_stack->setCurrentIndex(0);
}

void CentralView::showSettings()
{
	m_stack->setCurrentIndex(1);
}

void CentralView::showStats()
{}

void CentralView::deleteModels()
{
	if (m_torrents)
		delete m_torrents;

	if (m_users)
		delete m_users;

	m_torrents = 0l;
	m_users = 0l;
	m_currentModel = 0l;
}

void CentralView::refreshCurrentView()
{
	///@BUG Nesto ovde trigeruje modele da se ne updateuju kako treba...
	if (!m_currentModel)
		return;

	clearPropertiesView();
	m_currentModel->refresh();

	if (m_currentModel == m_torrents)
		showTorrents();
	else
		showUsers();

	updateLabels();
}

void CentralView::showHtmlProperties(const QString& relFieldValue)
{
	if (!m_currentModel)
		return;

	Model* model = (Model*) m_currentModel->createModel(relFieldValue);

	QStringList sl = model->getPropertiesMap();

	propertiesView->insertHtml(constructHtmlProperties(sl));

	delete model;
}

void CentralView::itemClicked(const QModelIndex & index)
{
	clearPropertiesView();

	if (!m_currentModel || !index.isValid())
	{
		return;
	}

	showHtmlProperties(index.data().toString());
}

QString CentralView::constructHtmlProperties(QStringList& properties)
{
	QString html("<html>");

	html.append("<table><tr><td>");

	if (m_currentModel->type() == SqlObjectsModel::TORRENT)
		html.append("<img src=\":/images/icons/torrent32.png\"></td><td><b>TORRENT</b></td>");
	else
		html.append("<img src=\":/images/icons/user32.png\"></td><td><b>USER</b></td>");

	html.append("</tr></table>");

	if (properties.size() % 2 == 0)
	{
		html.append("<br>");

		for (int i = 0; i < properties.size() - 1; ++i)
		{
			html.append("<b><font size='2'>" + properties[i] + "</font></b>");
			html.append("<br><font size='2'>");
			html.append(properties[++i] + "</font><br><br>");
		}

		html.append("<table></font>");
	}
	else
		html.append("Malformed properties list.");

	html.append("</html>");
	return html;
}

void CentralView::clearPropertiesView()
{
	//QTextBrowser* propertiesView;
	propertiesView->clear();
}

void CentralView::removeItem()
{
	//QListView* listView
	if (!m_currentModel || !listView->selectionModel()->hasSelection() || !listView->selectionModel()->selectedIndexes().first().isValid())
		return;

	if (QMessageBox::question(this, tr("Are you sure?"), tr("Are you sure you want to remove this item?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
		return;

	try
	{
		Model* model = (Model*) m_currentModel->createModel(listView->selectionModel()->selectedIndexes().first().data().toString());

		model->remove();

		delete model;
	}
	catch (Exception* ex)
	{
		ExceptionHandler::instance().protocolException(this->thread(), ex, TRUE);
		QMessageBox::warning(this, tr("QTracker"), tr("An uknown error occurred."));

		return;
	}

	refreshCurrentView();
}

void CentralView::slotExportTorrent()
{
	if (!m_currentModel || !listView->selectionModel()->hasSelection() || !listView->selectionModel()->selectedIndexes().first().isValid())
		return;

	try
	{
		Model* model = (Model*) m_currentModel->createModel(listView->selectionModel()->selectedIndexes().first().data().toString());

		ModelTorrent* torrent = dynamic_cast<ModelTorrent*>(model);

		ExportTorrentDialog dlg(torrent->name(), this);
		dlg.exec();

		delete torrent;
	}
	catch (Exception* ex)
	{
		ExceptionHandler::instance().protocolException(this->thread(), ex, TRUE);
		QMessageBox::warning(this, tr("QTracker"), tr("An uknown error occurred."));

		return;
	}
}

void CentralView::listViewContextMenuRequested(const QPoint& pos)
{
	QMenu menu(listView);

	menu.addAction(actionRefresh);
	menu.addSeparator();
	menu.addAction(actionRemoveItem);

	if (m_currentModel->type() == SqlObjectsModel::TORRENT)
	{
		menu.addAction(actionExportTorrent);
		menu.addAction(actionShowTorrentPropertiesDialog);
	}

	if (m_currentModel->type() == SqlObjectsModel::USER)
	{
		menu.addAction(actionShowUserPropertiesDialog);
	}

	menu.exec(mapToGlobal(pos));
}

void CentralView::showTorrentPropertiesDialog()
{
	if (!m_currentModel || !listView->selectionModel()->hasSelection() || !listView->selectionModel()->selectedIndexes().first().isValid())
		return;

	try
	{
		Model* model = (Model*) m_currentModel->createModel(listView->selectionModel()->selectedIndexes().first().data().toString());

		ModelTorrent* torrent = dynamic_cast<ModelTorrent*>(model);

		TorrentPropertiesDialog dlg(torrent, this);
		dlg.exec();

		delete torrent;
	}
	catch (Exception* ex)
	{
		ExceptionHandler::instance().protocolException(this->thread(), ex, TRUE);
		QMessageBox::warning(this, tr("QTracker"), tr("An uknown error occurred."));

		return;
	}
}

void CentralView::showUserPropertiesDialog()
{
	if (!m_currentModel || !listView->selectionModel()->hasSelection() || !listView->selectionModel()->selectedIndexes().first().isValid())
		return;

	try
	{
		Model* model = (Model*) m_currentModel->createModel(listView->selectionModel()->selectedIndexes().first().data().toString());

		ModelUser* user = dynamic_cast<ModelUser*>(model);

		UserPropertiesDialog dlg(user, this);
		dlg.exec();

		delete user;
	}
	catch (Exception* ex)
	{
		ExceptionHandler::instance().protocolException(this->thread(), ex, TRUE);
		QMessageBox::warning(this, tr("QTracker"), tr("An uknown error occurred."));

		return;
	}
}

void CentralView::listViewDoubleClicked(QModelIndex)
{
	if (m_currentModel->type() == SqlObjectsModel::TORRENT)
		showTorrentPropertiesDialog();
	else
		showUserPropertiesDialog();
}

void CentralView::numConnectionsChanged(int num_connections)
{
	lblConnections->setText(QString("%1").arg(num_connections));
}

void CentralView::setupWidgets()
{
	//Settings
	m_settingsWidget = new SettingsWidget(this);
	m_stack->addWidget(m_settingsWidget);
}

void CentralView::updateLabels()
{
	//Update labels
	int complete;
	int incomplete;

	try
	{
		Globals::instance().db()->countTotalPeers(&complete, &incomplete);
	}
	catch (Exception* ex)
	{
		ExceptionHandler::instance().protocolException(this->thread(), ex, TRUE);
		QMessageBox::warning(this, tr("QTracker"), ex->getMessage());
	}

	lblPeers->setText(QString("%1").arg(complete + incomplete));
	lblSeeders->setText(QString("%1").arg(complete));
	lblLeechers->setText(QString("%1").arg(incomplete));
}
